﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;

namespace NugetPublishWizard
{
    public class NugetRemote
    {
        public List<string> Output { get; private set; }
        private string DefaultNugetExePath = Environment.CurrentDirectory + @"\NuGet.exe";

        public bool Pack(string path)
        {
            Output = new List<string>();
            try
            {
                process(DefaultNugetExePath, string.Format("pack {0}", path));
                if (Output[Output.Count - 1].ToLower().Contains("success"))
                    return true;
            }
            catch (Exception ex)
            {
                Output.Clear();
                Output.Add(ex.Message);
            }
            return false;
        }

        public bool Publish(string id, string version, string source, string apikey, ref string output)
        {
            Output = new List<string>();
            try
            {
                process(DefaultNugetExePath,string.Format("publish -source {0} {1} {2} {3}", source, id, version, apikey));
                if (Output.Count != 0)
                    output = GetOutputString();
                if (Output[Output.Count - 1] == "Your package was published to the feed.")
                    return true;
            }
            catch (Exception ex)
            {
                Output.Clear();
                Output.Add(ex.Message);
            }
            return false;
        }

        public bool Remove(string id, string version, string source, string apikey, ref string output)
        {
            Output = new List<string>();
            try
            {
                process(DefaultNugetExePath, string.Format("delete -np -source {0} {1} {2} {3}", source, id, version, apikey));
                if (Output.Count != 0)
                    output = GetOutputString();
                if (Output[Output.Count - 1].ToLower().Contains("was deleted from the server"))
                    return true;
            }
            catch (Exception ex)
            {
                Output.Clear();
                Output.Add(ex.Message);
            }
            return false;
        }

        public bool Push(string path, string source, string apikey, ref string output)
        {
            Output = new List<string>();

            try
            {
                FileInfo file = new FileInfo(path);
                FileInfo dest = new FileInfo(string.Format(@"{0}\{1}", Environment.CurrentDirectory, file.Name));

                file.CopyTo(dest.FullName, true);
                try
                {
                    process(Environment.CurrentDirectory + @"\NuGet.exe", string.Format("push -source {0} {1} {2}", source, file.Name, apikey));
                    if (Output.Count != 0)
                        output = GetOutputString();
                    if (Output[Output.Count - 1] == "Your package was published to the feed.")
                        return true;
                }
                catch (Exception ex)
                {
                    Output.Clear();
                    Output.Add(ex.Message);
                }
                finally
                {
                    dest.Delete();
                }
            }
            catch (Exception ex)
            {
                Output.Clear();
                Output.Add(ex.Message);
            }

            return false;
        }

        private string GetOutputString()
        {
            StringBuilder result = new StringBuilder();
            foreach (string s in this.Output)
                result.AppendLine(s);
            return result.ToString();
        }

        private void process(string nugetEXEPath, string arguments)
        {
            Process process = new Process();
            process.StartInfo.FileName = nugetEXEPath;
            process.StartInfo.Arguments = arguments;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.ErrorDialog = false;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.EnableRaisingEvents = true;
            process.OutputDataReceived += process_OutputDataReceived;
            process.ErrorDataReceived += process_OutputDataReceived;
            process.Start();
            process.BeginErrorReadLine();
            process.BeginOutputReadLine();
            process.WaitForExit();
        }

        void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data == null)
                return;
            this.Output.Add(e.Data);
        }
    }
}
